package edu.hawaii.myisern.action;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.Set;

/**
 * A simplistic security filter for Bugzooky that ensures that the user is logged in
 * before allowing access to any secured pages.
 *
 * @author Tim Fennell
 */
public class SecurityFilter implements Filter {
  private static Set<String> publicUrls = new HashSet<String>();

  static {
      publicUrls.add("/index.jsp");
      publicUrls.add("/Index.action");
      publicUrls.add("/Login.action");
      publicUrls.add("/Logout.action");
      publicUrls.add("/default.css");
  }
  /** An error string, always displayed, but invisible if empty. */
  private String errorMessage = "";
  
  /**
   * Returns the error message, which may be empty.
   * 
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }
  
  /**
   * Set's the error message for the user.
   * 
   * @param errorMessage The error message. 
   */
  public void setErrorMessage(String errorMessage) {
    this.errorMessage = errorMessage;
  }

  /** 
   * Does nothing. 
   * @param filterConfig nothing.
   * @throws ServletException another exception
   */
  public void init(FilterConfig filterConfig) throws ServletException { 
    // does nothing
  }

  /** 
   * Checks to see if user is validated.  If the user successfully starts a
   * session or the page trying to be accessed is a "public url," it will 
   * process the request.  If not successfull, it will redirect to the login page.
   * @param servletRequest nothing.
   * @param servletResponse nothing.
   * @param filterChain nothing.
   * @throws IOException some exception
   * @throws ServletException another exception
   */
  public void doFilter(ServletRequest servletRequest, ServletResponse
      servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;

    if (request.getSession().getAttribute("user") == null) {

      // if url is a allowable, then pass through
      if (isPublicResource(request)) {
        filterChain.doFilter(request, response);
      }

      // if url is not allowable and user attribute not set, redirect to my login page.
      else {
        String targetUrl = URLEncoder.encode(request.getServletPath(), "UTF-8");
        setErrorMessage("Please login to access the current page.");
        response.sendRedirect(
                request.getContextPath() + "/index.jsp?targetUrl=" + targetUrl);
      }
    }

    // if user is set, then pass through url
    else {
      filterChain.doFilter(request, response);
    }
  }


  /**
   * Method that checks the request to see if it is for a publicly accessible resource.
   * @param request a http request.
   * @return all the good stuff.
   */
  protected boolean isPublicResource(HttpServletRequest request) {
    return publicUrls.contains(request.getServletPath());
  }


  /** Does nothing. */
  public void destroy() { 
    // does nothing
  }
}
